(ns utils.readDB
	(:import	(java.text DecimalFormat)
				(javax.swing.table DefaultTableModel))
				(:gen-class)
)

(defn map-one-record
	"Builds a map containing the fields and their respective data, of a record, from a Vector."
	[record-vec field-names]
		(loop [c1 (vec record-vec) c2 (vec field-names) result {}]
			(if (empty? c1)
				result
				(recur (pop c1) (pop c2) (assoc result (keyword (peek c2)) (peek c1))))))

(defn build-record-map
	"Builds a map containing all the records in a Vector."
	[vec-o-vec field-names row-count]
		(let [cloj-vec (vec (reverse vec-o-vec))]
			(loop [c1 cloj-vec nextkey row-count result {}]
				(if (empty? c1)
					{:map (dissoc result (keyword (.format (DecimalFormat. "00000000") (dec nextkey)))) :max-pk (- nextkey 2)}
					(let [df (DecimalFormat. "00000000")] (recur (pop c1) (inc nextkey) (assoc result (keyword (.format df nextkey)) (assoc (map-one-record (peek c1) field-names) (keyword "key") nextkey))
								))))))
(defn get-records
	"Get the records with the specified keys in reckeys."
	[records field-names reckeys]
	(for [key reckeys]
		(for [field-name field-names]
			((records key) (keyword field-name)))))

(defn get-field-names
	"Gets the names of the DB's fields."
	[fields]
	(for [field fields] (get field 0)))

(defn get-field-sizes
	"Gets the names of the DB's sizes."
	[fields]
	(for [field fields] (get field 1)))
	
(defn get-page
	"Returns N records of the database belonging to P page."
	[KeyList KeyListSize P N]
	(let [FirstKeyIndex (* (dec P) N) LastKeyIndex (* P N)]
		(if (> LastKeyIndex KeyListSize)
			(subvec (vec KeyList) FirstKeyIndex KeyListSize)
			(subvec (vec KeyList) FirstKeyIndex LastKeyIndex))))
			
(defn search
	"Searches records containing the specified values of name or/and location."
	[keyList dataB s-name s-location]
	(let [is-name (empty? s-name) is-location (empty? s-location)]
		(loop [lst (vec keyList) map (sorted-map)]
			(if (empty? lst)
				map
				(let [record (dataB (peek lst))]
					(if (and (or is-name (= s-name (record :name))) (or is-location (= s-location (record :location))))
						(let [df (DecimalFormat. "00000000")] (recur (pop lst) (assoc map (keyword (.format df (record :key))) record)))
						(recur (pop lst) map)))))))
(defn change-page
	"Sets the vector of a TableModel to a new vector containing the records at a certain page."
	[tableModel page n map-records fnames]
	(let [
		keys-map-records 	(keys map-records)
		reckeys 			(get-page keys-map-records (count keys-map-records) page n)
		table-data			(to-array-2d (get-records map-records fnames reckeys))
		table-columns		(into-array fnames)]
		(.setDataVector tableModel table-data table-columns)))

(defn del-records
	"Deletes records from memory."
	[table map key-vec]
	(loop [kys key-vec m map]
	(if (empty? kys)
		m
		(let [key (keyword (.format (DecimalFormat. "00000000") (peek kys)))]
			(recur (pop kys) (dissoc m key))))))

(defn change-record
	"Changes records from memory."
	[map record-key field-index field-names change]
	(let [
		key (keyword (.format (DecimalFormat. "00000000") record-key))
		record (map key)
		kfield (keyword (get (vec field-names) field-index))]
		(let [changed-record (assoc record kfield change)]
			(assoc map key changed-record))))
